'''
Created on Jul 9, 2011

@author: kafkef
'''

from PyQt4.QtGui import *
from PyQt4.QtCore import (QAbstractTableModel, QModelIndex, QVariant, Qt, QRect,
                          QSize) 

from dexen.system.client import ui
from dexen.system.client.proxy import JobProxy
from dexen.system.common.states import JobState

JOB_ID = 0
JOB_NAME = 1
JOB_STAT = 2
START_TIME = 3
ELAPSED_TIME = 4
TOTAL_BIRTH = 5
AVG_TIME_IND = 6
TOTAL_TASK_EXEC = 7

svr_proxy = ui.svr_proxy


class JobInfoModel(QAbstractTableModel):
    def __init__(self, info_items, parent=None):
        QAbstractTableModel.__init__(self, parent)
        self._info_items = info_items
        self._header = ["Task Name", "Success", "Failure"]
    
    def rowCount(self, index=QModelIndex()):
        return len(self._info_items)
    
    def columnCount(self, index=QModelIndex()):
        return 3

    def data(self, index, role):
        assert isinstance(index, QModelIndex)
        if not index.isValid(): return QVariant()
        
        if role == Qt.DisplayRole:
            return QVariant(self._info_items[index.row()][index.column()])
    
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role != Qt.DisplayRole:
            return QVariant()
        if orientation == Qt.Horizontal:
            return QVariant(self._header[section])


class MyLineEdit(QLineEdit):
    def __init__(self):
        QLineEdit.__init__(self)
        self.setReadOnly(True)
        #self.setFixedWidth(200)


class JobInfoPage(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.widgets = {}
        self._cur_job_id = None
        self._cur_job_states = {} #job_id:JobState
        self._create_widgets()
        
    def _create_widgets(self):
        # Create widgets
        self.widgets[JOB_ID] = MyLineEdit()
        self.widgets[JOB_NAME] = MyLineEdit()
        self.widgets[JOB_STAT] = MyLineEdit()
        self.widgets[START_TIME] = MyLineEdit()
        self.widgets[ELAPSED_TIME] = MyLineEdit()
        self.widgets[TOTAL_BIRTH] = MyLineEdit()
        self.widgets[AVG_TIME_IND] = MyLineEdit()
        self.widgets[TOTAL_TASK_EXEC] = MyLineEdit()
        self._table_view = QTableView()
        empty_label = QLabel("")
        breakdown_label = QLabel("Task executions breakdown:")

        # Configure widgets
        self._table_view.setModel(JobInfoModel([]))
        #self._table_view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        #self._table_view.setFixedWidth(400)
        header = self._table_view.horizontalHeader()
        assert isinstance(header, QHeaderView)
        #header.resizeSection(0, )
        #header.resizeSection(1, 10)
        header.setResizeMode(0, QHeaderView.Stretch)
        
        # Lay out widgets
        v_layout = QVBoxLayout()
        form_layout = QFormLayout()
        form_layout.addRow("Job id:", self.widgets[JOB_ID])
        form_layout.addRow("Job name:", self.widgets[JOB_NAME])
        form_layout.addRow("Job status:", self.widgets[JOB_STAT])
        form_layout.addRow("Start time:", self.widgets[START_TIME])
        form_layout.addRow("Elapsed time:", self.widgets[ELAPSED_TIME])
        form_layout.addRow("Total birth:", self.widgets[TOTAL_BIRTH])
        form_layout.addRow("Avg time per individual:", self.widgets[AVG_TIME_IND])
        #form_layout.addRow("Total task executions:", self.widgets[TOTAL_TASK_EXEC])
        v_layout.addLayout(form_layout)
        v_layout.addWidget(empty_label)
        v_layout.addWidget(breakdown_label)
        v_layout.addWidget(self._table_view)
        #v_layout.addStretch()
        self.setLayout(v_layout)

    def _update_widget(self, index, value):
        line_edit = self.widgets[index]
        assert isinstance(line_edit, MyLineEdit)
        line_edit.setText(str(value))
    
    def _update_widgets(self, job_state):
        assert isinstance(job_state, JobState)
        # update widgets
        self._update_widget(JOB_ID, job_state.job_id)
        self._update_widget(JOB_NAME, job_state.job_name)
        self._update_widget(JOB_STAT, job_state.get_status())
        self._update_widget(START_TIME, job_state.get_start_time())
        self._update_widget(ELAPSED_TIME, job_state.get_elapsed_time())
        self._update_widget(TOTAL_BIRTH, job_state.tot_births)
        self._update_widget(AVG_TIME_IND, job_state.get_avg_time_per_ind())
        #self._update_widget(TOTAL_TASK_EXEC, job_state.get)       
        tasks_info = job_state.get_tasks_info()
        model = JobInfoModel(tasks_info)
        self._table_view.setModel(model)
        #self._table_view.setFixedHeight(self._table_view.rowHeight(0)*10)
        #self._table_view.resizeColumnsToContents()
        #self._table_view.resizeColumnToContents(0)
    
    def update_cur_job_id(self, job_id):
        self._cur_job_id = job_id
        if not self._cur_job_states.has_key(job_id):
            self.on_refresh()
        else: # Restore the saved job state and update the display accordingly
            job_state = self._cur_job_states[job_id]
            self._update_widgets(job_state)
       
    def on_refresh(self):
        if self._cur_job_id is None:
            return
        # Retrieve the fresh job state from the server
        job_proxy = svr_proxy.get_job_cached(self._cur_job_id)
        assert isinstance(job_proxy, JobProxy)
        job_state = job_proxy.get_job_info()
        # Save the job state
        self._cur_job_states[job_state.job_id] = job_state
        self._update_widgets(job_state)
    
    